package com.gsocket.client;

import com.gsocket.event.check.CheckDecorator;
import com.gsocket.event.client.ClientListener;

import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;

public class GSocketClient {

    private Socket socket;
    private ClientListener clientListener;
    private String host;
    private int port;
    //    连接超时
    private int timeout = 5000;
    private int soTimeout = 5000;
    private boolean reConnect = false;
    public boolean connectState = false;

    public CheckDecorator checkDecorator;



    public int sendNum = 0;

    public void setReConnect(boolean reConnect) {
        this.reConnect = reConnect;
    }

    public GSocketClient(ClientListener clientListener, String host, int port) {
        this.clientListener = clientListener;
        this.host = host;
        this.port = port;
    }

    public GSocketClient(ClientListener clientListener, String host, int port, int timeout, int soTimeout) {
        this.clientListener = clientListener;
        this.host = host;
        this.port = port;
        this.timeout = timeout;
        this.soTimeout = soTimeout;
    }

    public Socket getSocket() {
        return socket;
    }

    public void connect() {
        if (!isServerClose()) {
            return;
        }
        socket = new Socket();
        try {
            socket.setSoTimeout(soTimeout);
            socket.connect(new InetSocketAddress(host, port), timeout);
            socket.setKeepAlive(true);
            ReceiviceThread receivice = new ReceiviceThread(this, clientListener);
            receivice.setReveCheck(checkDecorator);
            receivice.start();
            connectState = true;
            connectNum = 1;
        } catch (Exception e) {
            clientListener.connectFail(e);
            reconnect();
        }

    }

    public Boolean isServerClose() {
        try {
            socket.sendUrgentData(0xFF);//发送1个字节的紧急数据，默认情况下，服务器端没有开启紧急数据处理，不影响正常通信
            return false;
        } catch (Exception se) {
            return true;
        }
    }
//    public GSocketClient(String host, int port, ClientListener clientListener) throws IOException {
//        socket = new Socket();
//        socket.connect(new InetSocketAddress(host, port), 5000);
//        this.clientListener = clientListener;
//        ReceiviceThread receivice = new ReceiviceThread(this, clientListener);
//        receivice.start();
//    }
//
//    public GSocketClient(String host, int port, ClientListener clientListener, int timeout) throws IOException {
//        socket = new Socket();
//        socket.connect(new InetSocketAddress(host, port), timeout);
//        this.clientListener = clientListener;
//        ReceiviceThread receivice = new ReceiviceThread(this, clientListener);
//        receivice.start();
//    }

//    private void receiveMsg() {
//
//
//    }

    public void send(String message) {
        PrintWriter writer;
        try {
            writer = new PrintWriter(new OutputStreamWriter(
                    socket.getOutputStream()), true);
            writer.println(message);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void send(byte[] message) {
        try {
            sendNum = 0;
            socket.getOutputStream().write(message);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void close() {
        try {
            socket.shutdownOutput();
            socket.close();
            clientListener.close();
            connectState = false;
            reconnect();
        } catch (Exception e) {
//            e.printStackTrace();
        }
    }

    private int connectNum = 1;

    public void reconnect() {
        if (!reConnect) {
            return;
        }
//        connectNum = connectNum > 120 ? connectNum : ++connectNum;
//        int delay = connectNum * timeout;
        connectNum++;
        int delay = timeout;
        System.out.println("reconnect:" + connectNum);
        System.out.println("wait:" + delay);
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                connect();
            }
        }, delay);
    }
}
